MongoDB进阶(八)Spring整合MongoDB(Spring Data MongoDB) - CSDN博客

创建时间:2018/5/29 22:13
来源:https://blog.csdn.net/qq_16313365/article/details/70142729

MongoDB进阶(八)Spring整合MongoDB(Spring Data MongoDB)
2017年04月12日 19:29:42
阅读数:11288

        最近比较忙,忙的都没空理csdn了,今天我继续迈着魔鬼般的步伐,摩擦摩擦……总结下最近学到的MongoDB的知识。


1.认识Spring Data MongoDB


        之前还的确不知道Spring连集成Nosql的东西都实现了,还以为自己又要手动封装一个操作MongoDB的API呢,结果就发现了Spring Data MongoDB。不愧是Spring,真是给了我们春天,佩服的渣渣我目瞪狗呆……

        废话少说,看招。Spring Data其实是一个高级别的Spring Source项目,而Spring Data MongoDB仅仅是其中的一个子项目。Spring Data旨在为关系型数据库、非关系型数据、Map-Reduce框架、云数据服务等等提供统一的数据访问API。
        无论是哪种持久化存储, 数据访问对象(或称作为DAO,即Data Access Objects)通常都会提供对单一域对象的CRUD (创建、读取、更新、删除)操作、查询方法、排序和分页方法等。Spring Data则提供了基于这些层面的统一接口(CrudRepository,PagingAndSortingRepository)以及对持久化存储的实现。

Spring Data 包含多个子项目:

  • Commons - 提供共享的基础框架,适合各个子项目使用,支持跨数据库持久化

  • Hadoop - 基于 Spring 的 Hadoop 作业配置和一个 POJO 编程模型的 MapReduce 作业

  • Key-Value  - 集成了 Redis 和 Riak ,提供多个常用场景下的简单封装

  • Document - 集成文档数据库:CouchDB 和 MongoDB 并提供基本的配置映射和资料库支持

  • Graph - 集成 Neo4j 提供强大的基于 POJO 的编程模型

  • Graph Roo AddOn - Roo support for Neo4j

  • JDBC Extensions - 支持 Oracle RAD、高级队列和高级数据类型

  • JPA - 简化创建 JPA 数据访问层和跨存储的持久层功能

  • Mapping - 基于 Grails 的提供对象映射框架,支持不同的数据库

  • Examples - 示例程序、文档和图数据库

  • Guidance - 高级文档

2. HelloWorld

好了,说了这么多,还是用代码表现最为实在,老规矩,Hello World,我这里创建了一个Maven Java项目demo。

2.1 配置依赖

【pom.xml】
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.   
  5.     <groupId>com.jastar</groupId>  
  6.     <artifactId>demo</artifactId>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <packaging>jar</packaging>  
  9.   
  10.     <name>demo</name>  
  11.     <url>http://www.jastar-wang.tech</url>  
  12.   
  13.     <!-- 版本配置 -->  
  14.     <properties>  
  15.         <spring.version>4.1.4.RELEASE</spring.version>  
  16.         <spring.data.version>1.7.0.RELEASE</spring.data.version>  
  17.         <log4j.version>1.2.17</log4j.version>  
  18.     </properties>  
  19.   
  20.     <dependencies>  
  21.         <!-- 单元测试包 -->  
  22.         <dependency>  
  23.             <groupId>junit</groupId>  
  24.             <artifactId>junit</artifactId>  
  25.             <version>4.10</version>  
  26.             <scope>test</scope>  
  27.         </dependency>  
  28.   
  29.         <!-- spring核心包 -->  
  30.         <dependency>  
  31.             <groupId>org.springframework</groupId>  
  32.             <artifactId>spring-core</artifactId>  
  33.             <version>${spring.version}</version>  
  34.         </dependency>  
  35.         <dependency>  
  36.             <groupId>org.springframework</groupId>  
  37.             <artifactId>spring-context</artifactId>  
  38.             <version>${spring.version}</version>  
  39.         </dependency>  
  40.         <dependency>  
  41.             <groupId>org.springframework</groupId>  
  42.             <artifactId>spring-beans</artifactId>  
  43.             <version>${spring.version}</version>  
  44.         </dependency>  
  45.         <dependency>  
  46.             <groupId>org.springframework</groupId>  
  47.             <artifactId>spring-tx</artifactId>  
  48.             <version>${spring.version}</version>  
  49.         </dependency>  
  50.         <dependency>  
  51.             <groupId>org.springframework</groupId>  
  52.             <artifactId>spring-webmvc</artifactId>  
  53.             <version>${spring.version}</version>  
  54.         </dependency>  
  55.         <dependency>  
  56.             <groupId>org.springframework</groupId>  
  57.             <artifactId>spring-aop</artifactId>  
  58.             <version>${spring.version}</version>  
  59.         </dependency>  
  60.         <dependency>  
  61.             <groupId>org.springframework</groupId>  
  62.             <artifactId>spring-test</artifactId>  
  63.             <version>${spring.version}</version>  
  64.         </dependency>  
  65.   
  66.         <!-- 关系型数据库整合时需配置 如hibernate jpa等 -->  
  67.         <dependency>  
  68.             <groupId>org.springframework</groupId>  
  69.             <artifactId>spring-orm</artifactId>  
  70.             <version>${spring.version}</version>  
  71.         </dependency>  
  72.   
  73.         <!-- spring aop 关联 -->  
  74.         <dependency>  
  75.             <groupId>org.aspectj</groupId>  
  76.             <artifactId>aspectjweaver</artifactId>  
  77.             <version>1.8.7</version>  
  78.         </dependency>  
  79.   
  80.         <!-- log4j -->  
  81.         <dependency>  
  82.             <groupId>log4j</groupId>  
  83.             <artifactId>log4j</artifactId>  
  84.             <version>${log4j.version}</version>  
  85.         </dependency>  
  86.   
  87.         <!-- spring整合MongoDB -->  
  88.         <dependency>  
  89.             <groupId>org.springframework.data</groupId>  
  90.             <artifactId>spring-data-mongodb</artifactId>  
  91.             <version>${spring.data.version}</version>  
  92.         </dependency>  
  93.   
  94.     </dependencies>  
  95.   
  96.     <repositories>  
  97.         <repository>  
  98.             <id>spring-milestone</id>  
  99.             <name>Spring Maven MILESTONE Repository</name>  
  100.             <url>http://repo.spring.io/libs-milestone</url>  
  101.         </repository>  
  102.     </repositories>  
  103.   
  104.     <build>  
  105.         <plugins>  
  106.             <plugin>  
  107.                 <groupId>org.apache.maven.plugins</groupId>  
  108.                 <artifactId>maven-compiler-plugin</artifactId>  
  109.                 <configuration>  
  110.                     <source>1.7</source>  
  111.                     <target>1.7</target>  
  112.                 </configuration>  
  113.             </plugin>  
  114.         </plugins>  
  115.     </build>  
  116. </project>  

注意:这里我使用的是Spring Data MongoDB 1.7.0版本,截止当前发文时间最新稳定版本应该是1.10.1

2.2 映射实体类

【UserInfo.java】
  1. package com.jastar.demo.entity;  
  2.   
  3. import java.io.Serializable;  
  4. import java.sql.Timestamp;  
  5.   
  6. import org.springframework.data.annotation.Id;  
  7. import org.springframework.data.mongodb.core.index.IndexDirection;  
  8. import org.springframework.data.mongodb.core.index.Indexed;  
  9. import org.springframework.data.mongodb.core.mapping.Document;  
  10. import org.springframework.data.mongodb.core.mapping.Field;  
  11.   
  12. /** 
  13.  * 用户实体类 
  14.  * <p> 
  15.  * ClassName: UserInfo 
  16.  * </p> 
  17.  * <p> 
  18.  * Description:本类用来展示MongoDB实体类映射的使用 
  19.  * </p> 
  20.  * <p> 
  21.  * Copyright: (c)2017 Jastar·Wang,All rights reserved. 
  22.  * </p> 
  23.  *  
  24.  * @author Jastar·Wang 
  25.  * @date 2017年4月12日 
  26.  */  
  27. @Document(collection = "coll_user")  
  28. public class UserInfo implements Serializable {  
  29.   
  30.     /** serialVersionUID */  
  31.     private static final long serialVersionUID = 1L;  
  32.   
  33.     // 主键使用此注解  
  34.     @Id  
  35.     private String id;  
  36.   
  37.     // 字段使用此注解  
  38.     @Field  
  39.     private String name;  
  40.   
  41.     // 字段还可以用自定义名称  
  42.     @Field("myage")  
  43.     private int age;  
  44.   
  45.     // 还可以生成索引  
  46.     @Indexed(name = "index_birth", direction = IndexDirection.DESCENDING)  
  47.     @Field  
  48.     private Timestamp birth;  
  49.   
  50.     public String getId() {  
  51.         return id;  
  52.     }  
  53.   
  54.     public void setId(String id) {  
  55.         this.id = id;  
  56.     }  
  57.   
  58.     public String getName() {  
  59.         return name;  
  60.     }  
  61.   
  62.     public void setName(String name) {  
  63.         this.name = name;  
  64.     }  
  65.   
  66.     public int getAge() {  
  67.         return age;  
  68.     }  
  69.   
  70.     public void setAge(int age) {  
  71.         this.age = age;  
  72.     }  
  73.   
  74.     public Timestamp getBirth() {  
  75.         return birth;  
  76.     }  
  77.   
  78.     public void setBirth(Timestamp birth) {  
  79.         this.birth = birth;  
  80.     }  
  81.   
  82. }  

附录:
  • @Id - 用于字段级别,标记这个字段是一个主键,默认生成的名称是“_id”

  • @Document - 用于类,以表示这个类需要映射到数据库,您也可以指定映射到数据库的集合名称

  • @DBRef - 用于字段,以表示它将使用com.mongodb.DBRef进行存储。

  • @Indexed - 用于字段,表示该字段需要如何创建索引

  • @CompoundIndex - 用于类,以声明复合索引

  • @GeoSpatialIndexed - 用于字段,进行地理位置索引

  • @TextIndexed - 用于字段,标记该字段要包含在文本索引中

  • @Language - 用于字段,以设置文本索引的语言覆盖属性。

  • @Transient - 默认情况下,所有私有字段都映射到文档,此注解将会去除此字段的映射

  • @PersistenceConstructor - 标记一个给定的构造函数,即使是一个protected修饰的,在从数据库实例化对象时使用。构造函数参数通过名称映射到检索的DBObject中的键值。

  • @Value - 这个注解是Spring框架的一部分。在映射框架内,它可以应用于构造函数参数。这允许您使用Spring表达式语言语句来转换在数据库中检索的键值,然后再用它来构造一个域对象。为了引用给定文档的属性,必须使用以下表达式:@Value("#root.myProperty"),root要指向给定文档的根。

  • @Field - 用于字段,并描述字段的名称,因为它将在MongoDB BSON文档中表示,允许名称与该类的字段名不同。

  • @Version - 用于字段锁定,保存操作时检查修改。初始值是0,每次更新时自动触发。

2.3 整合配置

【db.properties】
[plain] view plain copy
  1. ###---The mongodb settings---  
  2. mongo.dbname=demo  
  3. mongo.host=localhost  
  4. mongo.port=27017  
  5. mongo.connectionsPerHost=8  
  6. mongo.threadsAllowedToBlockForConnectionMultiplier=4  
  7. mongo.connectTimeout=1000  
  8. mongo.maxWaitTime=1500  
  9. mongo.autoConnectRetry=true  
  10. mongo.socketKeepAlive=true  
  11. mongo.socketTimeout=1500  
  12. mongo.slaveOk=true  
  13. mongo.writeNumber=1  
  14. mongo.writeTimeout=0  
  15. mongo.writeFsync=true  
【spring-mgo.xml】
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:mongo="http://www.springframework.org/schema/data/mongo"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/context  
  7.           http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  8.           http://www.springframework.org/schema/data/mongo   
  9.           http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd  
  10.           http://www.springframework.org/schema/beans  
  11.           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  12.   
  13.     <!-- 读取属性文件 -->  
  14.     <context:property-placeholder location="classpath:db.properties" />  
  15.   
  16.     <!-- 启用注解支持 -->  
  17.     <context:annotation-config />  
  18.   
  19.     <!-- 扫描组件包 -->  
  20.     <context:component-scan base-package="com.jastar.demo" />  
  21.   
  22.     <!-- SpringData类型转换器 -->  
  23.     <mongo:mapping-converter id="mongoConverter">  
  24.         <mongo:custom-converters>  
  25.             <mongo:converter>  
  26.                 <bean class="com.jastar.demo.converter.TimestampConverter" />  
  27.             </mongo:converter>  
  28.         </mongo:custom-converters>  
  29.     </mongo:mapping-converter>  
  30.   
  31.     <!--   
  32.         MongoDB配置部分   
  33.         1.mongo:连接配置   
  34.         2.db-factory:相当于sessionFactory   
  35.         3.mongoTemplate:与数据库接口交互的主要实现类   
  36.     -->  
  37.     <mongo:mongo host="${mongo.host}" port="${mongo.port}">  
  38.         <mongo:options   
  39.             connections-per-host="${mongo.connectionsPerHost}"  
  40.             threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"  
  41.             connect-timeout="${mongo.connectTimeout}"   
  42.             max-wait-time="${mongo.maxWaitTime}"  
  43.             auto-connect-retry="${mongo.autoConnectRetry}"   
  44.             socket-keep-alive="${mongo.socketKeepAlive}"  
  45.             socket-timeout="${mongo.socketTimeout}"   
  46.             slave-ok="${mongo.slaveOk}"  
  47.             write-number="${mongo.writeNumber}"   
  48.             write-timeout="${mongo.writeTimeout}"  
  49.             write-fsync="${mongo.writeFsync}" />  
  50.     </mongo:mongo>  
  51.   
  52.     <mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongo" />  
  53.   
  54.     <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">  
  55.         <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />  
  56.         <constructor-arg name="mongoConverter" ref="mongoConverter" />  
  57.     </bean>  
  58.   
  59. </beans>  

说明:
mongo:options - 用于配置一些数据库连接设置信息
mongo:db-factory - 相当于Hibernate中的SessionFactory
mongoTemplate - 非常重要,整个与数据库的交互操作全是靠他,相当于Hibernate的HibernateTemplate

        另外,以上配置中有一个类型转换器,因为Spring Data MongoDB本身默认时间类型是java.util.Date,如果实体字段含有java.sql.Timestamp类型,需要自定义转换器进行转换,否则后续操作会报错(深有感触)!什么?不把转换器代码贴出来?别着急,文章最后有整个项目地址,去里面找吧……偷笑.GIF

2.4 Dao层参考实现

【BaseDaoImpl.java】

  1. package com.jastar.demo.dao.impl;  
  2.   
  3. import static org.springframework.data.mongodb.core.query.Criteria.where;  
  4.   
  5. import java.io.Serializable;  
  6. import java.lang.reflect.Field;  
  7. import java.lang.reflect.Method;  
  8. import java.lang.reflect.Modifier;  
  9. import java.util.ArrayList;  
  10. import java.util.HashMap;  
  11. import java.util.List;  
  12. import java.util.Map;  
  13.   
  14. import org.springframework.beans.factory.annotation.Autowired;  
  15. import org.springframework.data.annotation.Id;  
  16. import org.springframework.data.domain.Sort;  
  17. import org.springframework.data.domain.Sort.Direction;  
  18. import org.springframework.data.domain.Sort.Order;  
  19. import org.springframework.data.mongodb.core.MongoTemplate;  
  20. import org.springframework.data.mongodb.core.query.Query;  
  21. import org.springframework.data.mongodb.core.query.Update;  
  22.   
  23. import com.jastar.demo.dao.IBaseDao;  
  24. import com.jastar.demo.util.EmptyUtil;  
  25. import com.jastar.demo.util.PageModel;  
  26.   
  27. /** 
  28.  * 基本操作接口MongoDB数据库实现类 
  29.  * <p> 
  30.  * ClassName: BaseDaoImpl 
  31.  * </p> 
  32.  * <p> 
  33.  * Description:本实现类适用于MongoDB数据库,以下代码仅供参考,本人水平有限,可能会存在些许问题(如有更好方案可告知我,一定虚心学习), 
  34.  * 再次提醒,仅供参考!! 
  35.  * </p> 
  36.  * <p> 
  37.  * Copyright: (c)2017 Jastar·Wang,All rights reserved. 
  38.  * </p> 
  39.  *  
  40.  * @author Jastar·Wang 
  41.  * @date 2017年4月12日 
  42.  */  
  43. public abstract class BaseDaoImpl<T> implements IBaseDao<T> {  
  44.   
  45.     protected abstract Class<T> getEntityClass();  
  46.   
  47.     @Autowired  
  48.     protected MongoTemplate mgt;  
  49.   
  50.     @Override  
  51.     public void save(T entity) {  
  52.         mgt.save(entity);  
  53.     }  
  54.   
  55.     @Override  
  56.     public void update(T entity) {  
  57.   
  58.         // 反向解析对象  
  59.         Map<String, Object> map = null;  
  60.         try {  
  61.             map = parseEntity(entity);  
  62.         } catch (Exception e) {  
  63.             e.printStackTrace();  
  64.         }  
  65.   
  66.         // ID字段  
  67.         String idName = null;  
  68.         Object idValue = null;  
  69.   
  70.         // 生成参数  
  71.         Update update = new Update();  
  72.         if (EmptyUtil.isNotEmpty(map)) {  
  73.             for (String key : map.keySet()) {  
  74.                 if (key.indexOf("{") != -1) {  
  75.                     // 设置ID  
  76.                     idName = key.substring(key.indexOf("{") + 1, key.indexOf("}"));  
  77.                     idValue = map.get(key);  
  78.                 } else {  
  79.                     update.set(key, map.get(key));  
  80.                 }  
  81.             }  
  82.         }  
  83.         mgt.updateFirst(new Query().addCriteria(where(idName).is(idValue)), update, getEntityClass());  
  84.     }  
  85.   
  86.     @Override  
  87.     public void delete(Serializable... ids) {  
  88.         if (EmptyUtil.isNotEmpty(ids)) {  
  89.             for (Serializable id : ids) {  
  90.                 mgt.remove(mgt.findById(id, getEntityClass()));  
  91.             }  
  92.         }  
  93.   
  94.     }  
  95.   
  96.     @Override  
  97.     public T find(Serializable id) {  
  98.         return mgt.findById(id, getEntityClass());  
  99.     }  
  100.   
  101.     @Override  
  102.     public List<T> findAll() {  
  103.         return mgt.findAll(getEntityClass());  
  104.     }  
  105.   
  106.     @Override  
  107.     public List<T> findAll(String order) {  
  108.         List<Order> orderList = parseOrder(order);  
  109.         if (EmptyUtil.isEmpty(orderList)) {  
  110.             return findAll();  
  111.         }  
  112.         return mgt.find(new Query().with(new Sort(orderList)), getEntityClass());  
  113.     }  
  114.   
  115.     @Override  
  116.     public List<T> findByProp(String propName, Object propValue) {  
  117.         return findByProp(propName, propValue, null);  
  118.     }  
  119.   
  120.     @Override  
  121.     public List<T> findByProp(String propName, Object propValue, String order) {  
  122.         Query query = new Query();  
  123.         // 参数  
  124.         query.addCriteria(where(propName).is(propValue));  
  125.         // 排序  
  126.         List<Order> orderList = parseOrder(order);  
  127.         if (EmptyUtil.isNotEmpty(orderList)) {  
  128.             query.with(new Sort(orderList));  
  129.         }  
  130.         return mgt.find(query, getEntityClass());  
  131.     }  
  132.   
  133.     @Override  
  134.     public List<T> findByProps(String[] propName, Object[] propValue) {  
  135.         return findByProps(propName, propValue, null);  
  136.     }  
  137.   
  138.     @Override  
  139.     public List<T> findByProps(String[] propName, Object[] propValue, String order) {  
  140.         Query query = createQuery(propName, propValue, order);  
  141.         return mgt.find(query, getEntityClass());  
  142.     }  
  143.   
  144.     @Override  
  145.     public T uniqueByProp(String propName, Object propValue) {  
  146.         return mgt.findOne(new Query(where(propName).is(propValue)), getEntityClass());  
  147.     }  
  148.   
  149.     @Override  
  150.     public T uniqueByProps(String[] propName, Object[] propValue) {  
  151.         Query query = createQuery(propName, propValue, null);  
  152.         return mgt.findOne(query, getEntityClass());  
  153.     }  
  154.   
  155.     @Override  
  156.     public PageModel<T> pageAll(int pageNo, int pageSize) {  
  157.         return pageAll(pageNo, pageSize, null);  
  158.     }  
  159.   
  160.     @Override  
  161.     public PageModel<T> pageAll(int pageNo, int pageSize, String order) {  
  162.         return pageByProp(pageNo, pageSize, nullnull, order);  
  163.     }  
  164.   
  165.     @Override  
  166.     public PageModel<T> pageByProp(int pageNo, int pageSize, String param, Object value) {  
  167.         return pageByProp(pageNo, pageSize, param, value, null);  
  168.     }  
  169.   
  170.     @Override  
  171.     public PageModel<T> pageByProp(int pageNo, int pageSize, String param, Object value, String order) {  
  172.         String[] params = null;  
  173.         Object[] values = null;  
  174.         if (EmptyUtil.isNotEmpty(param)) {  
  175.             params = new String[] { param };  
  176.             values = new Object[] { value };  
  177.         }  
  178.         return pageByProps(pageNo, pageSize, params, values, order);  
  179.     }  
  180.   
  181.     @Override  
  182.     public PageModel<T> pageByProps(int pageNo, int pageSize, String[] params, Object[] values) {  
  183.         return pageByProps(pageNo, pageSize, params, values, null);  
  184.     }  
  185.   
  186.     @Override  
  187.     public PageModel<T> pageByProps(int pageNo, int pageSize, String[] params, Object[] values, String order) {  
  188.         // 创建分页模型对象  
  189.         PageModel<T> page = new PageModel<>(pageNo, pageSize);  
  190.   
  191.         // 查询总记录数  
  192.         int count = countByCondition(params, values);  
  193.         page.setTotalCount(count);  
  194.   
  195.         // 查询数据列表  
  196.         Query query = createQuery(params, values, order);  
  197.   
  198.         // 设置分页信息  
  199.         query.skip(page.getFirstResult());  
  200.         query.limit(page.getPageSize());  
  201.   
  202.         // 封装结果数据  
  203.         page.setList(mgt.find(query, getEntityClass()));  
  204.   
  205.         return page;  
  206.     }  
  207.   
  208.     @Override  
  209.     public int countByCondition(String[] params, Object[] values) {  
  210.         Query query = createQuery(params, values, null);  
  211.         Long count = mgt.count(query, getEntityClass());  
  212.         return count.intValue();  
  213.     }  
  214.   
  215.     /** 
  216.      * 创建带有where条件(只支持等值)和排序的Query对象 
  217.      *  
  218.      * @param params 
  219.      *            参数数组 
  220.      * @param values 
  221.      *            参数值数组 
  222.      * @param order 
  223.      *            排序 
  224.      * @return Query对象 
  225.      */  
  226.     protected Query createQuery(String[] params, Object[] values, String order) {  
  227.         Query query = new Query();  
  228.   
  229.         // where 条件  
  230.         if (EmptyUtil.isNotEmpty(params) && EmptyUtil.isNotEmpty(values)) {  
  231.             for (int i = 0; i < params.length; i++) {  
  232.                 query.addCriteria(where(params[i]).is(values[i]));  
  233.             }  
  234.         }  
  235.   
  236.         // 排序  
  237.         List<Order> orderList = parseOrder(order);  
  238.         if (EmptyUtil.isNotEmpty(orderList)) {  
  239.             query.with(new Sort(orderList));  
  240.         }  
  241.   
  242.         return query;  
  243.     }  
  244.   
  245.     /** 
  246.      * 解析Order字符串为所需参数 
  247.      *  
  248.      * @param order 
  249.      *            排序参数,如[id]、[id asc]、[id asc,name desc] 
  250.      * @return Order对象集合 
  251.      */  
  252.     protected List<Order> parseOrder(String order) {  
  253.         List<Order> list = null;  
  254.         if (EmptyUtil.isNotEmpty(order)) {  
  255.             list = new ArrayList<Order>();  
  256.             // 共有几组排序字段  
  257.             String[] fields = order.split(",");  
  258.             Order o = null;  
  259.             String[] item = null;  
  260.             for (int i = 0; i < fields.length; i++) {  
  261.                 if (EmptyUtil.isEmpty(fields[i])) {  
  262.                     continue;  
  263.                 }  
  264.                 item = fields[i].split(" ");  
  265.                 if (item.length == 1) {  
  266.                     o = new Order(Direction.ASC, item[0]);  
  267.                 } else if (item.length == 2) {  
  268.                     o = new Order("desc".equalsIgnoreCase(item[1]) ? Direction.DESC : Direction.ASC, item[0]);  
  269.                 } else {  
  270.                     throw new RuntimeException("排序字段参数解析出错");  
  271.                 }  
  272.                 list.add(o);  
  273.             }  
  274.         }  
  275.         return list;  
  276.     }  
  277.   
  278.     /** 
  279.      * 将对象的字段及值反射解析为Map对象<br> 
  280.      * 这里使用Java反射机制手动解析,并且可以识别注解为主键的字段,以达到根据id进行更新实体的目的<br> 
  281.      * key:字段名称,value:字段对应的值 
  282.      *  
  283.      * @param t 
  284.      *            要修改的对象 
  285.      * @return Map对象,注意:id字段的key封装为“{id字段名称}”,以供后续识别 
  286.      * @throws Exception 
  287.      */  
  288.     protected Map<String, Object> parseEntity(T t) throws Exception {  
  289.         Map<String, Object> map = new HashMap<String, Object>();  
  290.         /* 
  291.          * 解析ID 
  292.          */  
  293.         String idName = "";  
  294.         Field[] declaredFields = getEntityClass().getDeclaredFields();  
  295.         for (Field field : declaredFields) {  
  296.             if (field.isAnnotationPresent(Id.class)) {  
  297.                 field.setAccessible(true);  
  298.                 map.put("{" + field.getName() + "}", field.get(t));  
  299.                 idName = field.getName();  
  300.                 break;  
  301.             }  
  302.         }  
  303.         /* 
  304.          * 解析其他属性 
  305.          */  
  306.         Method[] methods = getEntityClass().getDeclaredMethods();  
  307.         if (EmptyUtil.isNotEmpty(methods)) {  
  308.             for (Method method : methods) {  
  309.                 if (method.getName().startsWith("get") && method.getModifiers() == Modifier.PUBLIC) {  
  310.                     String fieldName = parse2FieldName(method.getName());  
  311.                     if (!fieldName.equals(idName)) {  
  312.                         map.put(fieldName, method.invoke(t));  
  313.                     }  
  314.                 }  
  315.             }  
  316.         }  
  317.   
  318.         return map;  
  319.     }  
  320.   
  321.     /** 
  322.      * 将get方法名转换为对应的字段名称 
  323.      *  
  324.      * @param methodName 
  325.      *            如:getName 
  326.      * @return 如:name 
  327.      */  
  328.     private String parse2FieldName(String methodName) {  
  329.         String name = methodName.replace("get""");  
  330.         name = name.substring(01).toLowerCase() + name.substring(1);  
  331.         return name;  
  332.     }  
  333.   
  334. }  

说明:

        以上实现仅供参考某些实现点,mongoTemplate如何使用还要自己去详细的摸索,我也没办法,毕竟我也这样过来的,大多数方法都已经提供了,只是update方法不像关系型数据库那样,给个实体类就能更新,需要自己去想办法搞定。


【TestUseService.java】

  1. package com.jastar.test;  
  2.   
  3. import java.sql.Timestamp;  
  4. import java.util.List;  
  5.   
  6. import org.junit.Test;  
  7. import org.junit.runner.RunWith;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.test.context.ContextConfiguration;  
  10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  11.   
  12. import com.jastar.demo.entity.UserInfo;  
  13. import com.jastar.demo.service.UserService;  
  14. import com.jastar.demo.util.PageModel;  
  15.   
  16. @RunWith(SpringJUnit4ClassRunner.class)  
  17. @ContextConfiguration(locations = "classpath:spring-mgo.xml")  
  18. public class TestUserService {  
  19.   
  20.     @Autowired  
  21.     private UserService service;  
  22.   
  23.     @Test  
  24.     public void save() {  
  25.         UserInfo user = new UserInfo();  
  26.         user.setName("张三");  
  27.         user.setAge(25);  
  28.         user.setBirth(Timestamp.valueOf("2017-4-12 16:52:00"));  
  29.         service.save(user);  
  30.         System.out.println("已生成ID:" + user.getId());  
  31.     }  
  32.   
  33.     @Test  
  34.     public void find() {  
  35.         UserInfo user = service.find("58edf1b26f033406394a8a61");  
  36.         System.out.println(user.getName());  
  37.     }  
  38.   
  39.     @Test  
  40.     public void update() {  
  41.         UserInfo user = service.find("58edf1b26f033406394a8a61");  
  42.         user.setAge(18);  
  43.         service.update(user);  
  44.     }  
  45.   
  46.     @Test  
  47.     public void delete() {  
  48.         service.delete("58edef886f03c7b0fdba51b9");  
  49.     }  
  50.   
  51.     @Test  
  52.     public void findAll() {  
  53.         List<UserInfo> list = service.findAll("age desc");  
  54.         for (UserInfo u : list) {  
  55.             System.out.println(u.getName());  
  56.         }  
  57.     }  
  58.   
  59.     @Test  
  60.     public void findByProp() {  
  61.         List<UserInfo> list = service.findByProp("name""张三");  
  62.         for (UserInfo u : list) {  
  63.             System.out.println(u.getName());  
  64.         }  
  65.     }  
  66.   
  67.     @Test  
  68.     public void findByProps() {  
  69.         List<UserInfo> list = service.findByProps(new String[] { "name""age" }, new Object[] { "张三"18 });  
  70.         for (UserInfo u : list) {  
  71.             System.out.println(u.getName());  
  72.         }  
  73.     }  
  74.   
  75.     @Test  
  76.     public void pageAll() {  
  77.         PageModel<UserInfo> page = service.pageAll(110);  
  78.         System.out.println("总记录:" + page.getTotalCount() + ",总页数:" + page.getTotalPage());  
  79.         for (UserInfo u : page.getList()) {  
  80.             System.out.println(u.getName());  
  81.         }  
  82.     }  
  83.   
  84.     @Test  
  85.     public void pageByProp() {  
  86.         PageModel<UserInfo> page = service.pageByProp(110"name""张三");  
  87.         System.out.println("总记录:" + page.getTotalCount() + ",总页数:" + page.getTotalPage());  
  88.         for (UserInfo u : page.getList()) {  
  89.             System.out.println(u.getName());  
  90.         }  
  91.     }  
  92.   
  93. }  



更多知识,请参考官方文档:戳我戳我

更多代码,请参考本项目Git 地址:戳我戳我


版权声明:原创文章,开放分享,但请客官留个URL,蟹蟹~~如有纰漏,还请指出,以免误导后生! https://blog.csdn.net/qq_16313365/article/details/70142729
个人分类: MongoDB
所属专栏: MongoDB快速入门